local base = require "base"
local msghelper = require "tablehelper"
local timetool = require "timetool"
local timer = require "timer"
local filelog = require "filelog"
local logicmng = require "logicmng"
local mjcardtool = require "mjcardtool"
local tabletool = require "tabletool"
local configdao = require "configdao"
local gamelog = require "gamelog"
local msgproxy = require "msgproxy"
local globaldatadao = require "globaldatadao"
local cardreviewrecords = require "gamerecords"
require "enum"
local RoomGameLogic = {}
 
function RoomGameLogic.init(gameobj, tableobj)
	gameobj.tableobj = tableobj
	gameobj.stateevent[ETableState.TABLE_STATE_GAME_START] = RoomGameLogic.gamestart
	gameobj.stateevent[ETableState.TABLE_STATE_ONE_GAME_START] = RoomGameLogic.onegamestart
	gameobj.stateevent[ETableState.TABLE_STATE_ONE_GAME_END] = RoomGameLogic.onegameend
	gameobj.stateevent[ETableState.TABLE_STATE_DISBAND_GAME] = RoomGameLogic.disbandgame
	gameobj.stateevent[ETableState.TABLE_STATE_ONE_GAME_REAL_END] = RoomGameLogic.onegamerealend
	gameobj.stateevent[ETableState.TABLE_STATE_GAME_END] = RoomGameLogic.gameend
	gameobj.stateevent[ETableState.TABLE_STATE_CONTINUE] = RoomGameLogic.continue
	gameobj.stateevent[ETableState.TABLE_STATE_CONTINUE_AND_STANDUP] = RoomGameLogic.continue_and_standup
	gameobj.stateevent[ETableState.TABLE_STATE_CONTINUE_AND_LEAVE] = RoomGameLogic.continue_and_leave

	--初始化牌堆
	if mjcardtool.init_card_stacks ~= nil then
		mjcardtool.init_card_stacks(tableobj.conf.is_load_tongzi, tableobj.conf.is_load_tiaozi, tableobj.conf.is_load_wanzi, tableobj.conf.is_load_feng, tableobj.conf.is_load_jian, tableobj.conf.is_load_hua)
	end

	return true
end

function RoomGameLogic.run(gameobj)
	local f = nil
	while true do
		if gameobj.tableobj.state == ETableState.TABLE_STATE_WAIT_ALL_READY then
			break
		end

		f = gameobj.stateevent[gameobj.tableobj.state]
		if f == nil then
			break
		end
		f(gameobj)
	end
end

function RoomGameLogic.gamestart(gameobj)
	local tableobj = gameobj.tableobj

	RoomGameLogic.gamestart_inittable(gameobj)

	msghelper:report_table_state()

	tableobj.state = ETableState.TABLE_STATE_ONE_GAME_START
	--设置桌子已经开局
	tableobj.is_had_start = true
end

function RoomGameLogic.onegamestart(gameobj)
	local tableobj = gameobj.tableobj
	RoomGameLogic.onegamestart_inittable(gameobj)

	tableobj.curr_to_num = tableobj.curr_to_num + 1

	--初始化牌局回顾	
	tableobj.card_review_recoard = cardreviewrecords.new()
	tableobj.card_review_recoard.init(tableobj.gamerecords.id.."_"..tableobj.curr_to_num)

	--初始化桌位
	local roomseatlogic = logicmng.get_logicbyname("roomseatlogic")
	for  _, seat in pairs(tableobj.seats) do
		if not roomseatlogic.is_empty(seat) then
			roomseatlogic.onegamestart_initseat(seat)
		end
	end

	--初始化牌堆
	--tableobj.cards_stack = nncardtool.get_new_cards()
	--tableobj.cards_stack = nncardtool.get_fixed_cards()

	--msghelper:write_tableinfo_log("RoomGameLogic.onegamestart 1", tableobj.cards_stack)


	for _, seat in ipairs(tableobj.seats) do
		if RoomGameLogic.is_ingame(gameobj, seat) then
			for i=1, 4 do
				table.insert(seat.cards, table.remove(tableobj.cards_stack, 1))
			end
		end				
	end

	--msghelper:write_tableinfo_log("RoomGameLogic.onegamestart 2", tableobj.cards_stack, tableobj.seats)

	--通知client游戏开始
	RoomGameLogic.send_gamestart_notice(gameobj)

	tableobj.state = ETableState.TABLE_STATE_ONE_WAIT_GAME_START
	local timer_id = timer.settimer(140, "one_game_start")	
	if tableobj.state ~= ETableState.TABLE_STATE_ONE_WAIT_GAME_START then
		timer.cleartimer(timer_id)
	else
		tableobj.timer_id = timer_id
	end
end


function RoomGameLogic.continue(gameobj)
	local tableobj = gameobj.tableobj

	local roomtablelogic = logicmng.get_logicbyname("roomtablelogic")
	local roomseatlogic = logicmng.get_logicbyname("roomseatlogic")
end

function RoomGameLogic.continue_and_standup(gameobj)
	RoomGameLogic.continue(gameobj)
end

function RoomGameLogic.continue_and_leave(gameobj)
	
end


function RoomGameLogic.onegameend(gameobj)
	local tableobj = gameobj.tableobj
	if tableobj.timer_id >0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end

	local roomseatlogic = logicmng.get_logicbyname("roomseatlogic")
	for _, seat in pairs(tableobj.seats) do
		if not roomseatlogic.is_empty(seat) then
			seat.total_score = seat.total_score + seat.curr_score
		end
	end

	RoomGameLogic.send_game_result(gameobj)

	tableobj.state = ETableState.TABLE_STATE_ONE_GAME_REAL_END
end

function RoomGameLogic.onegamerealend(gameobj)
	local tableobj = gameobj.tableobj

	RoomGameLogic.onegameend_inittable(gameobj)

	tableobj.is_onegameend = true
	
	--初始化桌位和保存当前局胡息
	local roomseatlogic = logicmng.get_logicbyname("roomseatlogic")
	for _, seat in pairs(tableobj.seats) do
		if not roomseatlogic.is_empty(seat) then
			--修改玩家战绩信息
			RoomGameLogic.modify_player_record(gameobj, seat)

			roomseatlogic.onegameend_initseat(seat)
		end
	end

	if tableobj.curr_to_num < tableobj.retain_to_num then
		tableobj.state = ETableState.TABLE_STATE_WAIT_ALL_READY		
		local timer_id = timer.settimer(configdao.get_businessconfitem_by_index(100, 1000, "globalvarcfg", "nn_readystart_time")*100, "game_ready_start")
		if tableobj.state ~= ETableState.TABLE_STATE_WAIT_ALL_READY then
			timer.cleartimer(timer_id)
		else
			tableobj.timer_id = timer_id
		end
	else
		tableobj.state = ETableState.TABLE_STATE_GAME_END
	end
end

function RoomGameLogic.disbandgame(gameobj)
	local tableobj = gameobj.tableobj
	if tableobj.timer_id >0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end

	RoomGameLogic.send_game_result(gameobj)

	RoomGameLogic.onegameend_inittable(gameobj)

	--初始化桌位和保存当前局胡息
	local roomseatlogic = logicmng.get_logicbyname("roomseatlogic")
	for _, seat in pairs(tableobj.seats) do
		if not roomseatlogic.is_empty(seat) then
			--修改玩家战绩信息
			RoomGameLogic.modify_player_record(gameobj, seat)

			roomseatlogic.onegameend_initseat(seat)
		end
	end

	tableobj.state = ETableState.TABLE_STATE_GAME_END
end

function RoomGameLogic.gameend(gameobj)
	local tableobj = gameobj.tableobj
	tableobj.state = ETableState.TABLE_STATE_UNKNOW
	tableobj.terminal_time = timetool.get_time()
	tableobj.gamerecords.terminal_time = tableobj.terminal_time

	msghelper:report_table_state()

	msghelper:save_player_record()

	if tableobj.gamerecords ~= nil then
		gamelog.write_table_records(tableobj.gamerecords.id, tableobj.gamerecords.table_id, tableobj.gamerecords.gameid
				, tableobj.conf.room_type, tableobj.conf.game_type, tableobj.gamerecords.create_user_rid, tableobj.gamerecords.create_time
				, tableobj.gamerecords.create_user_rolename, tableobj.gamerecords.create_user_logo, tableobj.gamerecords.create_table_id, tableobj.gamerecords.playerrecordlist)
	end

	msgproxy.sendrpc_broadcastmsgto_tablesvrd("delete", tableobj.conf.gameid, tableobj.svr_id , tableobj.id)
	--强制踢掉玩家

	--检查桌子当前是否能够删除
	if tableobj.delete_table_timer_id <= 0 then
		tableobj.delete_table_timer_id = -1
	end

	tableobj.delete_table_timer_id = timer.settimer(300*100, "delete_table")
end

function RoomGameLogic.onsitdowntable(gameobj, seat)
	
end

function RoomGameLogic.send_banker_notice(gameobj)
	local tableobj = gameobj.tableobj
	local noticemsg = {}
	local seat = tableobj.seats[tableobj.banker_seat_index]
	noticemsg.rid = seat.rid
	noticemsg.roomsvr_seat_index = seat.index

	msghelper:sendmsg_to_alltableplayer("NNBankerNtc", noticemsg)
	tableobj.card_review_recoard.insert("NNBankerNtc", noticemsg, false)		
end

function RoomGameLogic.send_gamestart_notice(gameobj)
	local tableobj = gameobj.tableobj
	local noticemsg = {
		gameinfo = {}
	}

	msghelper:copy_table_gameinfo(noticemsg.gameinfo)
	msghelper:sendmsg_to_alltableplayer("GameStartNtc", noticemsg)

	tableobj.card_review_recoard.insert("GameStartNtc", noticemsg, false)
end

--通知结算信息
function RoomGameLogic.send_game_result(gameobj)
	local tableobj = gameobj.tableobj
	--通知游戏结算
	local noticemsg = {
		create_table_id = tableobj.conf.create_table_id,
		retain_to_num = tableobj.conf.retain_to_num,
		curr_to_num = tableobj.curr_to_num,
		pattern = tableobj.conf.pattern,
		zuozhuang = tableobj.conf.zuozhuang,
		is_gameend = 0,
		one_start_time = tableobj.one_start_time,
		playergameresultlist = {

		}
	}

	if noticemsg.retain_to_num <= noticemsg.curr_to_num 
		or tableobj.state == ETableState.TABLE_STATE_DISBAND_GAME then
		noticemsg.is_gameend = 1
	end
	
	local gameresutitem
	for index, seat in ipairs(tableobj.seats) do
		if RoomGameLogic.is_ingame(gameobj, seat) then
			gameresutitem = {

				rid = seat.rid,
				rolename = seat.playerinfo.rolename,
				logo = seat.playerinfo.logo,
				curr_score = seat.curr_score,
	 			total_score = seat.total_score,
				bankertag = seat.bankertag,
				cards = seat.final_cards,
				seat_index = seat.index,
				win_num = seat.win_num,
				tong_sha_num = seat.tong_sha_num,
				tong_pei_num = seat.tong_pei_num,
				niuniu_num = seat.niuniu_num,
				continue_banker_count = seat.continue_banker_count,
				card_review_id = tableobj.card_review_recoard.getid(),
			}

			table.insert(noticemsg.playergameresultlist, gameresutitem)		
		end	
	end

	msghelper:sendmsg_to_alltableplayer("NNGameResultNtc", noticemsg)

	if tableobj.gamerecords ~= nil then
		globaldatadao.save_tablerecord("insert", tableobj.gamerecords.id, tableobj.conf.gameid, noticemsg)
	end

	tableobj.card_review_recoard.insert("NNGameResultNtc", noticemsg, true)
end

function RoomGameLogic.is_ingame(gameobj, seat)
	return (seat.state == ESeatState.SEAT_STATE_PLAYING)
end

function RoomGameLogic.get_ingame_playernum(gameobj)
	local tableobj = gameobj.tableobj
	local playernum = 0
	for _, seat in ipairs(tableobj.seats) do
		if RoomGameLogic.is_ingame(gameobj, seat) then
			playernum = playernum + 1
		end
	end
	return playernum
end

function RoomGameLogic.modify_player_record(gameobj, seat)
	local tableobj = gameobj.tableobj
	for _, gamerecord in ipairs(tableobj.gamerecords.playerrecordlist) do
		if seat.rid == gamerecord.rid then
			gamerecord.rid = seat.rid
			gamerecord.total_score = seat.total_score
			gamerecord.win_num = seat.win_num
			gamerecord.tong_sha_num = seat.tong_sha_num
			gamerecord.tong_pei_num = seat.tong_pei_num
			gamerecord.niuniu_num = seat.niuniu_num
			gamerecord.continue_banker_count = seat.continue_banker_count
			gamerecord.rolename = seat.playerinfo.rolename
			gamerecord.logo = seat.playerinfo.logo
			break
		end
	end 
end

function RoomGameLogic.gamestart_inittable(gameobj)
	local tableobj = gameobj.tableobj
	tableobj.terminal_time = 0

	--表示游戏是否第一局
	tableobj.iswilldelete = 0
	tableobj.action_player_list = nil
	tableobj.cards_stack = nil     --当前牌堆
	tableobj.gamerecords = {
		id = msghelper:generate_table_key(),
		gameid = tableobj.conf.gameid,
		table_id = tableobj.conf.id,
		create_user_rid = tableobj.conf.create_user_rid,
		create_time = tableobj.conf.create_time,
		terminal_time =  0,
		create_user_rolename = tableobj.conf.create_user_rolename,
		create_user_logo = tableobj.conf.create_user_logo,
		create_table_id  = tableobj.conf.create_table_id,
		playerrecordlist = {}
	}
	--初始化战绩
	local roomseatlogic = logicmng.get_logicbyname("roomseatlogic")
	for _, seat in ipairs(tableobj.seats) do
		if not roomseatlogic.is_empty(seat) then
			local gamerecord = {
					rid = seat.rid,
 					total_score = 0, 
					win_num = 0,
					tong_sha_num = 0,
					tong_pei_num = 0,
					niuniu_num = 0,
					continue_banker_count = 0,
					rolename = seat.playerinfo.rolename,
					logo = seat.playerinfo.logo,
			}
			table.insert(tableobj.gamerecords.playerrecordlist, gamerecord)
		end
	end	

	RoomGameLogic.onegamestart_inittable(gameobj)	 
end

function RoomGameLogic.onegamestart_inittable(gameobj)
	local tableobj = gameobj.tableobj
	tableobj.one_start_time = timetool.get_time()
	tableobj.banker_seat_index = 0     --当前庄家位置
	tableobj.curr_actionplayer_rid = 0
	tableobj.curr_actionplayer_cards = nil

	if tableobj.timer_id >= 0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end
end

function RoomGameLogic.onegameend_inittable(gameobj)
	local tableobj = gameobj.tableobj
	tableobj.one_start_time = 0
	tableobj.curr_actionplayer_rid = 0
	tableobj.curr_actionplayer_cards = nil
	if tableobj.timer_id >= 0 then
		timer.cleartimer(tableobj.timer_id)
		tableobj.timer_id = -1
	end
end

function RoomGameLogic.standup_clear_seat(gameobj, seat)
	local roomseatlogic = logicmng.get_logicbyname("roomseatlogic")
	roomseatlogic.clear_seat(seat)
end


--@ des 检查是否结当前是否操作完成
function RoomGameLogic.check_end_action(gameobj)
	local tableobj = gameobj.tableobj

	local is_all = true
	for _, player_action in pairs(tableobj.action_player_list) do
		if not tableobj.seats[player_action.roomsvr_seat_index].is_tuoguan and player_action.action_state < 1 then
			is_all = false
			break 
		end
	end

	return is_all 
end

--@ des 计算指定玩家的得分
function RoomGameLogic.calculate_score(gameobj, card_type, call_score)
	local tableobj = gameobj.tableobj
	if tableobj.pointcountcfg == nil then
		tableobj.pointcountcfg = configdao.get_business_conf(100, 1000, "pointcountcfg")
	end

	local id = tableobj.conf.pattern.key.."_"..card_type
	local multiple = 1
	for _, pointcountitem in ipairs(tableobj.pointcountcfg) do
		if pointcountitem.id == id then
			multiple = pointcountitem.multiple
			break
		end
	end

	if call_score <= 0 then
		return (tableobj.conf.base_score*multiple)
	else
		return (tableobj.conf.base_score*multiple*call_score)
	end
	return 0
end

return RoomGameLogic